﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System.Net.Moles;

namespace TestProject
{
    /// <summary>
    /// Base class for faking web resposes during tests. This class uses Moles.
    /// </summary>
    [TestClass()]
    public class WebResponseTestBase : IDisposable
    {
        private bool disposed;
        private Stream mockedResponseStream;
        private MHttpWebResponse mockedResponse;
        
        /// <summary>
        /// Determines if WebRequest.GetResponse was called during test
        /// </summary>
        protected bool GetResponseCalled { get; set; }

        /// <summary>
        /// Determines if WebResponse.GetResponseStream was called during test
        /// </summary>
        protected bool GetResponseStreamCalled { get; set; }

        /// <summary>
        /// Test initialize
        /// </summary>
        [TestInitialize()]
        public void BaseTestInitialize()
        {
            mockedResponseStream = new MemoryStream();
            mockedResponse = new MHttpWebResponse();
            mockedResponse.BehaveAsDefaultValue();
            MHttpWebRequest.AllInstances.GetResponse = (x) =>
            {
                GetResponseCalled = true;
                return mockedResponse;
            };
            MHttpWebResponse.AllInstances.GetResponseStream = (x) =>
            {
                GetResponseStreamCalled = true;
                return mockedResponseStream;
            };
            GetResponseCalled =
                GetResponseStreamCalled = false;
        }

        /// <summary>
        /// Cleanup for class
        /// </summary>
        [TestCleanup()]
        public void BaseTestCleanup()
        {
            if (mockedResponseStream != null) 
                mockedResponseStream.Dispose();
        }

        /// <summary>
        /// Sets the web response that will be sent when WebRequest is called
        /// </summary>
        /// <param name="response"></param>
        protected void SetWebResponse(string response)
        {
            using (StringReader sr = new StringReader(response))
            {
                System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
                byte[] contentAsBytes = encoding.GetBytes(sr.ReadToEnd());
                mockedResponseStream.Write(contentAsBytes, 0, contentAsBytes.Length);
            }
            mockedResponseStream.Seek(0, SeekOrigin.Begin);
        }

        #region IDisposable Members

        /// <summary>
        /// Called to dispose the object
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Called to dispose the object
        /// </summary>
        /// <param name="disposing">If disposing equals true, the method has been called directly
        /// or indirectly by a user's code. Managed and unmanaged resources can be disposed.
        /// If disposing equals false, the method has been called by the runtime from inside the finalizer 
        /// and you should not reference other objects. Only unmanaged resources can be disposed.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (mockedResponseStream != null)
                    {
                        mockedResponseStream.Dispose();
                    }
                }
                disposed = true;
            }
        }

        #endregion
    }
}
